//  Inside Microsoft Exchange 2007 Web Services
//  Chapter 8
//
//  Copyright (c) 2007 David Sterling, Ben Spain, Mark Taylor, Huw Upshall, Michael Mainer.
//  All rights reserved.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using ProxyHelpers.EWS;

namespace CreateCalendarViewForToday
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeServiceBinding binding = new ExchangeServiceBinding();
            binding.Url = @"https://yourServer/ews/Exchange.asmx";
            binding.Credentials = new NetworkCredential(
                "username",
                "password",
                "domain");

            RequestAndDisplayCalendarView(
                            binding,
                            CreateCalendarViewForToday());
        }

        /// <summary>
        /// Create a one day CalendarView starting from 'now'.  'Now' is relative to
        /// the current timezone settings of the operating system. (Listing 8-19)
        /// </summary>
        public static CalendarViewType CreateCalendarViewForToday()
        {
            // First create a date time instance which represents "today,
            // 12:00:00am"
            //
            DateTime dtToday12AM =
                new DateTime(DateTime.Now.Year, DateTime.Now.Month,
                    DateTime.Now.Day, 0, 0, 0, DateTimeKind.Local);

            CalendarViewType calendarView = new CalendarViewType();
            calendarView.StartDate = dtToday12AM;
            calendarView.EndDate = calendarView.StartDate.AddDays(1);
            calendarView.MaxEntriesReturned = 25;
            // Don't forget to set the specified flag
            calendarView.MaxEntriesReturnedSpecified = true;

            return calendarView;
        }

        /// <summary>
        /// This method will walk through the user's (represented by the supplied
        /// ExchangeServiceBinding) calendar outputing to the console a rendered
        /// view of all appointments found in the supplied CalendarView (Listing 8-20)
        /// </summary>
        /// <param name="binding">Fully initialized Exchange Service Binding</param>
        /// <param name="calendarView">Calendar view to send as part of the
        /// request</param>
        public static void RequestAndDisplayCalendarView(
            ExchangeServiceBinding binding,
            CalendarViewType calendarView)
        {
            // Prepare the Find Item Request
            //
            FindItemType findItemRequest = new FindItemType();

            // Set the ID(s) of the Find Item Request to be the Distinguished
            // Folder, 'calendar'.
            //
            findItemRequest.ParentFolderIds = new DistinguishedFolderIdType[] { new DistinguishedFolderIdType() };
            ((DistinguishedFolderIdType)findItemRequest.ParentFolderIds[0]).Id =
                DistinguishedFolderIdNameType.calendar;
            findItemRequest.Traversal = ItemQueryTraversalType.Shallow;

            // Prepare an Item shape type that defines how the items in view will be
            // returned. This could easily be extended with additional properties to 
            // be supplied by the caller
            //
            ItemResponseShapeType itemShapeDefinition = new ItemResponseShapeType();
            itemShapeDefinition.BaseShape = DefaultShapeNamesType.Default;

            // Add our itemShape definition and the caller-supplied calendarView to
            // the FindItem request.  Because CalendarView is a 'paging' type, it is
            // set via the Item property
            //
            findItemRequest.Item = calendarView;
            findItemRequest.ItemShape = itemShapeDefinition;

            // Send the request via the Exchange Service Binding
            FindItemResponseType findItemResponse =
                binding.FindItem(findItemRequest);

            // Verify that the FindItem request was successfull
            if (findItemResponse.ResponseMessages.Items[0].ResponseClass !=
                ResponseClassType.Success)
            {
                // Indicate that we have a problem
                throw new Exception(String.Format(
                    "Unable to get calendar view\r\n{0}\r\n{1}",
                    findItemResponse.ResponseMessages.Items[0].ResponseCode,
                    findItemResponse.ResponseMessages.Items[0].MessageText));
            }

            // Success, now let's get at the Calendar Items contained in our
            // response
            //
            FindItemResponseMessageType findItemResponseMessage =
                (FindItemResponseMessageType)findItemResponse.
                    ResponseMessages.Items[0];
            ArrayOfRealItemsType findItemResponseItems =
                (ArrayOfRealItemsType)findItemResponseMessage.RootFolder.Item;

            // And Printout a nice console-esqe view of our appointments
            //
            Console.WriteLine(
                "There are {0} appointments between \r\n\t{1} on {2} and\r\n" +
                "\t{3} on {4}\r\n------------------------------\r\n",
                findItemResponseMessage.RootFolder.TotalItemsInView,
                calendarView.StartDate.ToLongTimeString(),
                calendarView.StartDate.ToLongDateString(),
                calendarView.EndDate.ToLongTimeString(),
                calendarView.EndDate.ToLongDateString());

            for (int x = 0;
                x < findItemResponseMessage.RootFolder.TotalItemsInView;
                x++)
            {
                // This explicit cast is safe for use because the CalendarView will
                // restrict the result set to CalendarItemTypes only
                //
                CalendarItemType currentCalendarItem =
                    (CalendarItemType)findItemResponseItems.Items[x];
                Console.WriteLine(currentCalendarItem.Subject);

                // Exchange stores all calendaring data in UTC time, therefore, out
                // of convenience to the caller, we will convert
                // them to LocalTime before displaying them.
                //
                Console.WriteLine("\tStarts at: {0} on {1}",
                    currentCalendarItem.Start.ToLocalTime().ToShortTimeString(),
                    currentCalendarItem.Start.ToLocalTime().DayOfWeek);
                Console.WriteLine("\tEnds at:   {0} on {1}",
                    currentCalendarItem.End.ToLocalTime().ToShortTimeString(),
                    currentCalendarItem.End.ToLocalTime().DayOfWeek);
                Console.WriteLine();
            }
        } 
    }
}
